package logique.parser;

import java.io.File;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.swing.SwingWorker;

import logique.parser.factories.ATTFactory;
import logique.parser.factories.ATVFactory;
import logique.parser.factories.ClassementFactory;
import logique.parser.factories.TailleVilleFactory;
import logique.reseau.Reseau;
import logique.reseau.Route;
import logique.reseau.Troncon;
import logique.reseau.Ville;
import logique.reseau.atouts.AtoutTouristiqueTroncon;
import logique.reseau.atouts.AtoutTouristiqueVille;
import logique.reseau.caracteristiques.Peage;
import logique.reseau.caracteristiques.Radar;

import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;

/**
 * 
 * @author camille
 *
 */
public class NetWorkReader {
	
	private Parser parser;
	private final ElementHandler elagueur;
	
	public NetWorkReader(Parser parser) {
		this.parser = parser;
		
		elagueur = new ElementHandler() {
			public void onStart(ElementPath path) {
				// rien...
			}

			public void onEnd(ElementPath path) {

				// on recupere le noeud
				Element row = path.getCurrent();

				// on coupe le noeud
				row.detach();
			}
		};
	}
	
	public SwingWorker<Reseau, Void> getWorkerOnePass() {
		return new SwingWorker<Reseau, Void>() {
			@Override
			protected Reseau doInBackground() throws Exception {
				final Reseau reseau = new Reseau(parser.getControleur());

				ElementHandler handlerVille = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien ...
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "ville"
						Element row = path.getCurrent();

						try {
							Ville ville = handleVille(row);
							reseau.addVille(ville);
						}
						catch (Exception e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				ElementHandler handlerRoute = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien ...
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "ville"
						Element row = path.getCurrent();

						try {
							Route route = handleRouteOnePass(row, reseau);
							reseau.addRoute(route);
						}
						catch (Exception e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.VILLE_NODE_NAME, handlerVille);
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME, handlerRoute);
				saxReader.setDefaultHandler(elagueur);
				saxReader.read(parser.getURLreseau());

				reseau.setId(parser.getURLreseau().getFile().substring(parser.getURLreseau().getFile().lastIndexOf('/') + 1, parser.getURLreseau().getFile().lastIndexOf('.')));

				return reseau;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}
	
	public SwingWorker<Void, Void> getWorkerSegmentation() throws ParserException {
		if (parser.getURLreseau() == null) {
			throw new ParserException("Pas de fichier reseau selectionne");
		}
		
		return new SwingWorker<Void, Void>() {
			
			final long fileSize = new File(parser.getURLreseau().getFile()).length();
			long bytesRead = 0;
			
			@Override
			protected Void doInBackground() throws Exception {

				ElementHandler handlerVille = new ElementHandler() {
					public void onStart(ElementPath path) {
						firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Segmentation d'un noeud ville");
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "ville"
						Element row = path.getCurrent();
						bytesRead += row.asXML().length();
						setProgress((int)(100.0f*((float)bytesRead/(float)fileSize)));
						
						try {
							parser.getNWriter().handleVilleFileSystem(row);
						}
						catch (Exception e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				ElementHandler handlerRoute = new ElementHandler() {
					public void onStart(ElementPath path) {
						firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Segmentation d'un noeud route");
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "ville"
						Element row = path.getCurrent();
						bytesRead += row.asXML().length();
						setProgress((int)(100.0f*((float)bytesRead/(float)fileSize)));
						
						try {
							parser.getNWriter().handleRouteFileSystem(row);
						}
						catch (Exception e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.VILLE_NODE_NAME, handlerVille);
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME, handlerRoute);
				saxReader.setDefaultHandler(elagueur);
				saxReader.read(parser.getURLreseau());

				firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Fermeture des balises");
				parser.getNWriter().finishAllFiles();
				firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Termine");

				return null;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}
	
	public SwingWorker<Hashtable<String, Ville>, Void> wLVSegmented() {
		return new SwingWorker<Hashtable<String, Ville>, Void>() {
			@Override
			protected Hashtable<String, Ville> doInBackground() throws Exception {

				final Hashtable<String, Ville> villes = new Hashtable<String, Ville>();

				ElementHandler handlerVille = new ElementHandler() {
					public void onStart(ElementPath path) {
						firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Analyse d'un noeud ville");
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "ville"
						Element row = path.getCurrent();

						try {
							// on analyse le noeud "ville"
							Ville ville = handleVille(row);
							villes.put(ville.getNom(), ville);
						}
						catch (Exception e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}

				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.DESC_NODE_NAME + "/" + Parser.VILLE_NODE_NAME, handlerVille);
				saxReader.setDefaultHandler(elagueur);

				File dir = new File(parser.getWorkspace() + File.separator + Parser.VILLES_DIR);
				for (File vF : dir.listFiles()) {
					saxReader.read(vF.toURI().toURL());
				}

				return villes;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}

	public SwingWorker<Hashtable<String, Ville>, Void> wLVUnsegmented() {
		return new SwingWorker<Hashtable<String, Ville>, Void>() {
			@Override
			protected Hashtable<String, Ville> doInBackground() throws Exception {

				final Hashtable<String, Ville> villes = new Hashtable<String, Ville>();

				ElementHandler handlerVille = new ElementHandler() {
					public void onStart(ElementPath path) {
						firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Analyse d'un noeud ville");
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "ville"
						Element row = path.getCurrent();

						try {
							// on analyse le noeud "ville"
							Ville ville = handleVille(row);
							villes.put(ville.getNom(), ville);
						}
						catch (Exception e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				ElementHandler handlerTroncon = new ElementHandler() {
					public void onStart(ElementPath path) {
						firePropertyChange(Parser.STATE_PROPERTY_NAME, null, "Recherche de ville(s) non declaree(s) dans un troncon");
					}

					@SuppressWarnings("unchecked")
					public void onEnd(ElementPath path) {

						// on recupere le noeud "troncon"
						Element row = path.getCurrent();

						// on verifie que les villes ont bien ete declarees
						for (Iterator i = row.elementIterator(); i.hasNext();) {
							Element element = (Element) i.next();

							if (element.getName().toLowerCase().equals(Parser.VILLE1_NODE_NAME)) {
								verifieDeclaration(villes, element.getStringValue().toLowerCase());
							}

							if (element.getName().toLowerCase().equals(Parser.VILLE2_NODE_NAME)) {
								verifieDeclaration(villes, element.getStringValue().toLowerCase());
							}
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.VILLE_NODE_NAME, handlerVille);
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME + "/" + Parser.TRONCON_NODE_NAME, handlerTroncon);
				saxReader.setDefaultHandler(elagueur);
				saxReader.read(parser.getURLreseau());
				
				for(Ville ville : parser.getVillesToAddToFS()){
					villes.put(ville.getNom(), ville);
				}
				
				for(Ville ville : parser.getVillesToRemoveFromFS()){
					villes.remove(ville.getNom());
				}
				
				return villes;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}
	
	public SwingWorker<Hashtable<String, Route>, Void> wLR() {
		return new SwingWorker<Hashtable<String, Route>, Void>() {
			@Override
			protected Hashtable<String, Route> doInBackground() throws Exception {

				final Hashtable<String, Route> routes = new Hashtable<String, Route>();

				ElementHandler handlerRoute = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien...
					}

					public void onEnd(ElementPath path) {

						// on recupere le noeud "route"
						Element row = path.getCurrent();

						Route route = handleRouteMultiPass(row);

						routes.put(route.getNom(), route);

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();

				if (parser.segmentationDone()) {

					saxReader.addHandler("/" + Parser.DESC_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME, handlerRoute);
					saxReader.setDefaultHandler(elagueur);

					File dir = new File(parser.getWorkspace() + File.separator + Parser.ROUTES_DIR);

					for (File rF : dir.listFiles()) {
						saxReader.read(rF.toURI().toURL());
					}
				}
				else {
					saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME, handlerRoute);
					saxReader.setDefaultHandler(elagueur);
					saxReader.read(parser.getURLreseau());
					
					for(Route route : parser.getRoutesToAddToFS()){
						routes.put(route.getNom(), route);
					}
					
					for(Route route : parser.getRoutesToRemoveFromFS()){
						routes.remove(route.getNom());
					}
				}

				return routes;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}
	
	public SwingWorker<LinkedList<Troncon>, Void> wLTSegmented(final Route route) {
		return new SwingWorker<LinkedList<Troncon>, Void>() {
			@Override
			protected LinkedList<Troncon> doInBackground() throws Exception {

				final LinkedList<Troncon> troncons = new LinkedList<Troncon>();

				ElementHandler handlerTroncon = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien...
					}

					@SuppressWarnings("unchecked")
					public void onEnd(ElementPath path) {

						// on recupere le noeud "route"
						Element row = path.getCurrent();

						try {
							Troncon troncon = handleTronconMultiPass(parser.getControleur().getVilles(), row);
							troncon.setRoute(route);
							troncons.add(troncon);
						}
						catch (ParserException e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.DESC_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME + "/" + Parser.TRONCON_NODE_NAME, handlerTroncon);
				saxReader.setDefaultHandler(elagueur);

				File routeFile = new File(parser.getWorkspace() + File.separator + Parser.ROUTES_DIR + File.separator + route.getNom() + Parser.FILE_EXT);

				if (!routeFile.exists()) {
					throw new ParserException("Le fichier " + route.getNom() + "n'existe pas");
				}

				saxReader.read(routeFile);

				return troncons;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}

	public SwingWorker<LinkedList<Troncon>, Void> wLTUnsegmented(final Route route) {
		return new SwingWorker<LinkedList<Troncon>, Void>() {
			@Override
			protected LinkedList<Troncon> doInBackground() throws Exception {

				final LinkedList<Troncon> troncons = new LinkedList<Troncon>();

				ElementHandler handlerRoute = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien...
					}

					@SuppressWarnings("unchecked")
					public void onEnd(ElementPath path) {

						// on recupere le noeud "route"
						Element row = path.getCurrent();

						Element nomNode = row.element(Parser.NOM_NODE_NAME);

						if (nomNode.getStringValue().toLowerCase().equals(route.getNom().toLowerCase())) {
							// on recupere les troncons
							List tronconsElements = row.elements(Parser.TRONCON_NODE_NAME);

							for (Iterator i = tronconsElements.iterator(); i.hasNext();) {
								Element tronconElement = (Element) i.next();
								try {
									Troncon troncon = handleTronconMultiPass(parser.getControleur().getVilles(), tronconElement);
									troncon.setRoute(route);
									troncons.add(troncon);
								}
								catch (ParserException pe) {
									pe.printStackTrace();
								}
							}
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME, handlerRoute);
				saxReader.setDefaultHandler(elagueur);
				saxReader.read(parser.getURLreseau());

				for(Troncon troncon : parser.getTronconsToAddToFS()){
					if(troncon.getRoute().equals(route)){
						troncons.add(troncon);
					}
				}
				
				for(Troncon troncon : parser.getTronconsToRemoveFromFS()){
					for(Troncon candidat : troncons){
						if(troncon.equals(candidat)){
							troncons.remove(candidat);
						}
					}
				}
				
				return troncons;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}
	
	public SwingWorker<LinkedList<Troncon>, Void> wLTSegmented(final Ville ville) {
		return new SwingWorker<LinkedList<Troncon>, Void>() {
			@Override
			protected LinkedList<Troncon> doInBackground() throws Exception {

				final LinkedList<Troncon> troncons = new LinkedList<Troncon>();

				ElementHandler handlerTroncon = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien...
					}

					@SuppressWarnings("unchecked")
					public void onEnd(ElementPath path) {

						// on recupere le noeud "route"
						Element row = path.getCurrent();

						try {
							Troncon troncon = handleTronconMultiPass(parser.getControleur().getVilles(), row);
							troncon.setRoute(parser.getControleur().getRoutes().get(getParentRoute(row).toLowerCase()));
							troncons.add(troncon);
						}
						catch (ParserException e) {
							e.printStackTrace();
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.DESC_NODE_NAME + "/" + Parser.TRONCON_NODE_NAME, handlerTroncon);
				saxReader.setDefaultHandler(elagueur);

				File routeFile = new File(parser.getWorkspace() + File.separator + Parser.VILLES_DIR + File.separator + ville.getNom() + Parser.FILE_EXT);

				if (!routeFile.exists()) {
					throw new ParserException("Le fichier " + ville.getNom() + "n'existe pas");
				}

				saxReader.read(routeFile);

				return troncons;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}

	public SwingWorker<LinkedList<Troncon>, Void> wLTUnsegmented(final Ville ville) {
		return new SwingWorker<LinkedList<Troncon>, Void>() {
			@Override
			protected LinkedList<Troncon> doInBackground() throws Exception {

				final LinkedList<Troncon> troncons = new LinkedList<Troncon>();

				ElementHandler handleTroncon = new ElementHandler() {
					public void onStart(ElementPath path) {
						// rien...
					}

					@SuppressWarnings("unchecked")
					public void onEnd(ElementPath path) {

						// on recupere le noeud "route"
						Element row = path.getCurrent();

						Element villeNode = row.element(Parser.VILLE1_NODE_NAME);

						if (villeNode.getStringValue().toLowerCase().equals(ville.getNom().toLowerCase())) {
							// on recupere les troncons
							try {
								Troncon troncon = handleTronconMultiPass(parser.getControleur().getVilles(), row);
								troncon.setRoute(parser.getControleur().getRoutes().get(getParentRoute(row).toLowerCase()));
								troncons.add(troncon);
							}
							catch (ParserException pe) {
								pe.printStackTrace();
							}
						}

						villeNode = row.element(Parser.VILLE2_NODE_NAME);

						if (villeNode.getStringValue().toLowerCase().equals(ville.getNom().toLowerCase())) {
							// on recupere les troncons
							try {
								troncons.add(handleTronconMultiPass(parser.getControleur().getVilles(), row));
							}
							catch (ParserException pe) {
								pe.printStackTrace();
							}
						}

						// on coupe le noeud
						row.detach();
					}
				};

				SAXReader saxReader = new SAXReader();
				saxReader.addHandler("/" + Parser.ROOT_NODE_NAME + "/" + Parser.ROUTE_NODE_NAME, handleTroncon);
				saxReader.setDefaultHandler(elagueur);
				saxReader.read(parser.getURLreseau());

				for(Troncon troncon : parser.getTronconsToAddToFS()){
					if(troncon.getVille1().equals(ville)||troncon.getVille2().equals(ville)){
						troncons.add(troncon);
					}
				}
				
				for(Troncon troncon : parser.getTronconsToRemoveFromFS()){
					for(Troncon candidat : troncons){
						if(troncon.equals(candidat)){
							troncons.remove(candidat);
						}
					}
				}
				
				return troncons;
			}

			@Override
			protected void done() {
				setProgress(100);
			}
		};
	}

	@SuppressWarnings("unchecked")
	private Ville handleVille(Element villeElement) {
		Ville ville = new Ville();

		for (Iterator i = villeElement.elementIterator(); i.hasNext();) {
			Element element = (Element) i.next();

			if (element.getName().toLowerCase().equals(Parser.NOM_NODE_NAME)) {
				ville.setNom(element.getStringValue().toLowerCase());
			}

			if (element.getName().toLowerCase().equals(Parser.TYPE_NODE_NAME)) {
				ville.setTaille(TailleVilleFactory.getInstance().getInstanceTailleVille(element.getStringValue().toLowerCase()));
			}

			if (element.getName().toLowerCase().equals(Parser.TOURIST_NODE_NAME)) {

				AtoutTouristiqueVille atv = ATVFactory.getInstance().getInstanceATV(element.getStringValue().toLowerCase());
				if (atv != null) {
					ville.addAtoutTouristique(atv);
				}
			}
		}

		return ville;
	}

	@SuppressWarnings("unchecked")
	private Route handleRouteMultiPass(Element routeElement) {
		Route route = new Route();

		for (Iterator i = routeElement.elementIterator(); i.hasNext();) {
			Element element = (Element) i.next();

			if (element.getName().toLowerCase().equals(Parser.NOM_NODE_NAME)) {
				route.setNom(element.getStringValue().toLowerCase());
			}

			if (element.getName().toLowerCase().equals(Parser.TYPE_NODE_NAME)) {
				route.setClassement(ClassementFactory.getInstance().getInstanceClassement(element.getStringValue().toLowerCase()));
			}
		}

		return route;
	}

	@SuppressWarnings("unchecked")
	private Route handleRouteOnePass(Element routeElement, Reseau reseau) throws ParserException {
		Route route = new Route();

		for (Iterator i = routeElement.elementIterator(); i.hasNext();) {
			Element element = (Element) i.next();

			if (element.getName().toLowerCase().equals(Parser.NOM_NODE_NAME)) {
				route.setNom(element.getStringValue().toLowerCase());
			}

			if (element.getName().toLowerCase().equals(Parser.TYPE_NODE_NAME)) {
				route.setClassement(ClassementFactory.getInstance().getInstanceClassement(element.getStringValue().toLowerCase()));
			}

			if (element.getName().toLowerCase().equals(Parser.TRONCON_NODE_NAME)) {
				Troncon troncon = handleTronconOnePass(reseau, element);
				route.addTroncon(troncon);
			}
		}

		return route;
	}

	@SuppressWarnings("unchecked")
	private Troncon handleTronconOnePass(Reseau reseau, Element tronconElement) throws ParserException {

		Troncon troncon = new Troncon();

		for (Iterator i = tronconElement.elementIterator(); i.hasNext();) {
			Element element = (Element) i.next();

			if (element.getName().toLowerCase().equals(Parser.VILLE1_NODE_NAME)) {
				verifieDeclaration(reseau.getVilles(), element.getStringValue().toLowerCase());
				troncon.setVille1(reseau.getVilles().get(element.getStringValue().toLowerCase()));
			}

			if (element.getName().toLowerCase().equals(Parser.VILLE2_NODE_NAME)) {
				verifieDeclaration(reseau.getVilles(), element.getStringValue().toLowerCase());
				troncon.setVille2(reseau.getVilles().get(element.getStringValue().toLowerCase()));
			}

			if (element.getName().toLowerCase().equals(Parser.VITESSE_NODE_NAME)) {
				troncon.setVitesse(Integer.parseInt(element.getStringValue()));
			}

			if (element.getName().toLowerCase().equals(Parser.TOURIST_NODE_NAME)) {
				AtoutTouristiqueTroncon att = ATTFactory.getInstance().getInstanceATT(element.getStringValue());
				if (att != null) {
					troncon.addAtoutTouristique(att);
				}
			}

			if (element.getName().toLowerCase().equals(Parser.RADAR_NODE_NAME)) {
				if (element.getStringValue().toLowerCase().equals(Parser.IND_POSITIVE)) {
					troncon.addCaracteristique(Radar.getInstance());
				}
			}

			if (element.getName().toLowerCase().equals(Parser.PAYANT_NODE_NAME)) {
				if (element.getStringValue().toLowerCase().equals(Parser.IND_POSITIVE)) {
					troncon.addCaracteristique(Peage.getInstance());
				}
			}

			if (element.getName().toLowerCase().equals(Parser.LONGUEUR_NODE_NAME)) {
				troncon.setLongueur(Integer.parseInt(element.getStringValue()));
			}
		}

		return troncon;
	}

	@SuppressWarnings("unchecked")
	private Troncon handleTronconMultiPass(Hashtable<String, Ville> villes, Element tronconElement) throws ParserException {

		Troncon troncon = new Troncon();

		for (Iterator i = tronconElement.elementIterator(); i.hasNext();) {
			Element element = (Element) i.next();

			if (element.getName().toLowerCase().equals(Parser.VILLE1_NODE_NAME)) {

				if (villes.get(element.getStringValue().toLowerCase()) == null) {
					throw new ParserException("La ville " + element.getStringValue() + " n'a pas ete cree");
				}

				troncon.setVille1(villes.get(element.getStringValue().toLowerCase()));
			}

			if (element.getName().toLowerCase().equals(Parser.VILLE2_NODE_NAME)) {
				if (villes.get(element.getStringValue().toLowerCase()) == null) {
					throw new ParserException("La ville " + element.getStringValue() + " n'a pas ete cree");
				}
				troncon.setVille2(villes.get(element.getStringValue().toLowerCase()));
			}

			if (element.getName().toLowerCase().equals(Parser.VITESSE_NODE_NAME)) {
				troncon.setVitesse(Integer.parseInt(element.getStringValue()));
			}

			if (element.getName().toLowerCase().equals(Parser.TOURIST_NODE_NAME)) {
				AtoutTouristiqueTroncon att = ATTFactory.getInstance().getInstanceATT(element.getStringValue());
				if (att != null) {
					troncon.addAtoutTouristique(att);
				}
			}

			if (element.getName().toLowerCase().equals(Parser.RADAR_NODE_NAME)) {
				if (element.getStringValue().toLowerCase().equals(Parser.IND_POSITIVE)) {
					troncon.addCaracteristique(Radar.getInstance());
				}
			}

			if (element.getName().toLowerCase().equals(Parser.PAYANT_NODE_NAME)) {
				if (element.getStringValue().toLowerCase().equals(Parser.IND_POSITIVE)) {
					troncon.addCaracteristique(Peage.getInstance());
				}
			}

			if (element.getName().toLowerCase().equals(Parser.LONGUEUR_NODE_NAME)) {
				troncon.setLongueur(Integer.parseInt(element.getStringValue()));
			}
		}

		return troncon;
	}
	
	@SuppressWarnings("unchecked")
	private String getParentRoute(Element tronconElement){
		if(tronconElement.attribute(Parser.ROUTE_NODE_NAME) != null){
			return tronconElement.attributeValue(Parser.ROUTE_NODE_NAME).toLowerCase();
		}
		else{
			Element routeElement = tronconElement.getParent();
			
			for (Iterator i = routeElement.elementIterator(); i.hasNext();) {
				Element element = (Element) i.next();

				if (element.getName().toLowerCase().equals(Parser.NOM_NODE_NAME)) {
					return element.getStringValue().toLowerCase();
				}
			}
			
			return null;
		}
	}
	
	private Ville verifieDeclaration(Hashtable<String, Ville> villes, String nomVille) {
		Ville ville = villes.get(nomVille);

		if (ville == null) {
			ville = new Ville();
			ville.setNom(nomVille);

			villes.put(ville.getNom(), ville);
		}

		return ville;
	}
}
